﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Linq;
using BankCreditPortfolio.DAL.Entities;
using BankCreditPortfolio.DAL.Services;
using BankCreditPortfolio.Models;

namespace BankCreditPortfolio.Areas.Admin.Models
{
    public class AddTariffModel : IBaseModel<Tariff>
    {

        public AddTariffModel()
        {
            Currencies = (new CurrencyService()).CreateQuery().ToList();
        }

        public int TariffId { get; set; }

        [Display(Name = "Title")]
        [Required, StringLength(255)]
        public string Title { get; set; }

        [Display(Name = "Description")]
        [Required, StringLength(255, MinimumLength = 4)]
        public string Description { get; set; }

        [Display(Name = "Fine (the amount of penalty for arrears of payment)")]
        [Required, Range(1, 100)]
        public float Fine { get; set; }

        [Display(Name = "Currency")]
        [Required]
        public int CurrencyId { get; set; }

        public List<Currency> Currencies { get; set; }

        [Display(Name = "Percent - value from 1 to 100")]
        [Required, Range(1, 100)]
        public virtual int CreditPercent { get; set; }

        [Display(Name = "Require Guarantor")]
        [Required]
        public bool RequireGuarantor { get; set; }

        [Display(Name = "First Payment (in percents of all sum) - value from 1 to 100")]
        [Required, Range(1, 100)]
        public decimal FirstPayment { get; set; }

        [Display(Name = "Other Payments (in percents of all sum) - value from 1 to 100")]
        [Required, Range(1, 100)]
        public decimal OtherPayments { get; set; }

        [Display(Name = "Minimum Sum")]
        [Required, Range(1, 2000000000)]
        public decimal Min { get; set; }

        [Display(Name = "Maximum Sum")]
        [Required, Range(1, 2000000000)]
        public decimal Max { get; set; }

        [Display(Name = "Term")]
        public DateTime Time { get; set; }

        [Display(Name = "Years (number of credit term years) - value from 0 to 10")]
        [Required, Range(0, 10)]
        public virtual int Years { get; set; }

        [Display(Name = "Months (number of credit term months) - value from 1 to 12")]
        [Required, Range(1, 12)]
        public virtual int Months { get; set; }

        [Display(Name = "Early Repayment Fine (the amount of penalty for early repayment)")]
        [Required, Range(1, 100)]
        public virtual int EarlyRepaymentFine { get; set; }

        public IBaseModel<Tariff> MapFrom(Tariff @from)
        {
            Title = from.Title;
            Description = from.Description;
            Fine = from.Fine;
            CurrencyId = from.Currency.CurrencyId;
            Description = from.Description;
            TariffId = from.TariffId;
            CreditPercent = from.CreditPercent;
            Fine = from.Fine;
            Max = from.Max;
            Min = from.Min;
            FirstPayment = from.FirstPayment;
            OtherPayments = from.OtherPayments;
            RequireGuarantor = from.NumberOfGuarantors > 0;
            Months = from.Time.Month - 1;
            Years = from.Time.Year - 2000;
            Title = from.Title;
            EarlyRepaymentFine = from.EarlyRepaymentFine;
            return this;
        }

        public Tariff MapTo(Tariff to)
        {
            to.CreditPercent = CreditPercent;
            to.Description = Description;
            to.Fine = Fine;
            to.FirstPayment = FirstPayment;
            to.Max = Max;
            to.Min = Min;
            to.NumberOfGuarantors = RequireGuarantor ? 1 : 0;
            to.OtherPayments = OtherPayments;
            to.Title = Title;
            to.Currency = (new CurrencyService()).Find(CurrencyId);
            to.Time =
                 DateTime.ParseExact(
                     "01." + String.Format("{0:00}", Months + 1) + "." + String.Format("{0:0000}", Years + 2000),
                     "dd.MM.yyyy", new CultureInfo("en-US", true));
            to.EarlyRepaymentFine = EarlyRepaymentFine;
            return to;
        }

        public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            if (Min >= Max)
                yield return new ValidationResult("Max value must be greater then Min value", new[] {"Min", "Max"});
            if (FirstPayment < OtherPayments)
                yield return new ValidationResult("First Payment must not be less then other payments", new[] { "FirstPayment" , "OtherPayments" });
            else if (FirstPayment + OtherPayments > 100)
                yield return new ValidationResult("First Payment and Other Payments sum is more than 100%", new[] { "FirstPayment", "OtherPayments" });
            var tariffService = new TariffService();
            var sameTitle = tariffService.GetByTitle(Title);
            if (sameTitle != null && sameTitle.TariffId != TariffId)
                yield return new ValidationResult("Title must be unique", new[] { "Title" });
        }
    }
}